<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;

/**
 * 资讯
 * 内容中包含图像、视频文件，统一使用类UBB代码格式
 * 图像：[image]fid[/image]，其中fid为UploadFile编号
 * 视频：[video]fid[/video]，其中fid为UploadFile编号
 *
 * Class Article
 * @package app\models
 *
 * @property integer $id
 * @property integer $uid
 * @property integer $cid
 * @property string $title
 * @property integer $cover_img_fid
 * @property string $intro
 * @property string $content
 * @property string $tags
 * @property integer $status
 * @property integer $add_time
 * @property integer $pub_time
 * @property string $remark
 *
 * @property ArticleCategory $category 关联分类
 * @property array $tagList 关联标签列表
 * @property User $user 关联用户
 * @property integer $praiseCount 被赞次数
 * @property integer $blameCount 被贬次数
 * @property integer $commentCount 被评论数
 * @property UploadFile $coverImg 关联封面图片
 */
class Article extends ActiveRecord
{
    const STATUS_DRAFT = 1; // 草稿
    const STATUS_WAIT = 2; // 待审核
    const STATUS_PUBLISHED = 3; // 已发布
    const STATUS_REFUSED = 4; // 已拒绝
    const STATUS_DELETED = 0; // 已删除

    /**
     * @inheritDoc
     */
    public function rules()
    {
        return [
            [['uid', 'cid', 'cover_img_fid', 'status', 'add_time', 'pub_time'], 'integer'],
            [['cid', 'title', 'content', 'status', 'add_time'], 'required'],
            ['title', 'string', 'max'=>256],
            [['intro', 'tags'], 'string', 'max'=>512],
            ['tags', function($attribute, $params) {
                if (count(explode(',', $this->tags)) > 12) {
                    $this->addError($attribute, '最多只能输入12个标签。');
                }
            }],
            [['content', 'remark'], 'safe'],
        ];
    }

    /**
     * 关联分类
     * @return \yii\db\ActiveQuery
     */
    public function getCategory()
    {
        return $this->hasOne(ArticleCategory::className(), ['id'=>'cid']);
    }
    
    /**
     * 关联的标签列表
     * @return \yii\db\ActiveQuery
     */
    public function getTagList()
    {
        return $this->hasMany(ArticleTag::className(), ['id'=>'tid'])->viaTable(ArticleTagMap::tableName(), ['aid'=>'id']);
    }
    
    /**
     * 关联的用户
     * @return \yii\db\ActiveQuery
     */
    public function getUser()
    {
        return $this->hasOne(User::className(), ['id'=>'uid']);
    }
    
    /**
     * 被赞次数
     * @return integer
     */
    public function getPraiseCount()
    {
        return ArticlePraise::find()->where(['aid'=>$this->id])->count();
    }
    
    /**
     * 被贬次数
     * @return integer
     */
    public function getBlameCount()
    {
        return ArticleBlame::find()->where(['aid'=>$this->id])->count();
    }

    /**
     * 被评论数
     * @return int
     */
    public function getCommentCount()
    {
        return ArticleComment::find()->where(['aid'=>$this->id])->count();
    }
    
    /**
     * 关联的封面图片
     * @return \yii\db\ActiveQuery
     */
    public function getCoverImg()
    {
        return $this->hasOne(UploadFile::className(), ['id'=>'cover_img_fid']);
    }

    /**
     * 同步处理标签内容，步骤如下：
     * 1.如果不是新添加的资讯内容，将所有关联的标签饮用次数提前减1，因为后面会全部加1，同时将tag_map的关联删除，后面会重新建立新关联
     * 2.逐个处理当前标签，如果没有则新建，创建tag_map关联，统一将标签引用次数加1
     * 3.删除引用次数为0的标签
     * @inheritdoc
     */
    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        $trans = Yii::$app->db->beginTransaction();
        if (!$insert) {
            foreach (ArticleTagMap::find()->where(['aid'=>$this->id])->each() as $_tag_map) {
                ArticleTag::updateAllCounters(['num'=>-1], ['id'=>$_tag_map->tid]);
                $_tag_map->delete();
            }
        }
        if (!empty($this->tags)) {
            $tags = preg_split('/,| /', $this->tags);
            foreach ($tags as $tag) {
                $_tag = ArticleTag::find()->where(['name'=>$tag])->one();
                if (empty($_tag)) {
                    $_tag = new ArticleTag();
                    $_tag->name = $tag;
                    $_tag->num = 0;
                }
                $_tag->num = $_tag->num + 1;
                $_tag->save();
                $_tag_map = new ArticleTagMap();
                $_tag_map->aid = $this->id;
                $_tag_map->tid = $_tag->id;
                $_tag_map->save();
            }
        }
        ArticleTag::deleteAll(['num'=>0]);
        $trans->commit();
    }
}
